/* eslint-disable @typescript-eslint/consistent-type-assertions */
import systemService from '@/services/system';
import { ILoginResp, IUserInfoResp } from '@/services/system/types';
import { IRootDispatch } from '@/store';
import { fetchAuthData } from '@/utils/tools';
import { MenuDataItem } from '@ant-design/pro-layout';
import { authHelper } from '@bud-fe/utils';

interface ILoginResultPayload {
  // 是否开启自动登录（only for 品牌黄）
  autoLogin?: boolean;
  // 登录接口的结果
  loginResult: ILoginResp;
}

const userModel = {
  state: {
    // 用户基本信息
    baseInfo: undefined,
    // 用户角色信息
    roles: [],
    // 用户拥有的菜单
    menuData: [],
  } as Partial<IUserInfoResp & { menuData: MenuDataItem[] }>,

  reducers: {
    updateUserInfo(prevState, payload: Partial<IUserInfoResp>) {
      return { ...prevState, ...payload };
    },
    updateMenu(prevState, payload: MenuDataItem[] | undefined) {
      return { ...prevState, menuData: payload || [] };
    },
  },

  effects: (dispatch: IRootDispatch) => ({
    /**
     * 处理登录成功后的结果
     * 登录成功后：1）获取用户信息并同步到store；2）获取菜单权限并同步到store
     * @param payload
     * @param rootState
     * @returns
     */
    async handleLoginResult(payload: ILoginResultPayload) {
      const { autoLogin = true, loginResult } = payload;
      const { tokenName, tokenValue } = loginResult;
      if (!tokenName || !tokenValue) {
        return null;
      }
      // 不勾选“自动登录”时，配置token在cookie的有效期为session
      authHelper.config({ cookiesConfig: { session: !autoLogin } });
      authHelper.setToken(tokenName, tokenValue);
      dispatch.user.fetchUserInfo();
      const data = await fetchAuthData();
      const { menuData } = data;
      dispatch.user.updateMenu(menuData || []);
      return data;
    },
    /**
     * 登出
     */
    logout() {
      return systemService
        .logout()
        .then((res) => res?.code === 200)
        .finally(() => {
          authHelper.removeToken();
          dispatch.user.updateUserInfo({ baseInfo: undefined, roles: [] });
        });
    },
    /**
     * 获取用户信息并更新至store
     */
    async fetchUserInfo() {
      const data = await systemService.getUserInfo();
      if (data) {
        dispatch.user.updateUserInfo(data);
      }
    },
  }),
};

export default userModel;
